<template>
  <!-- 任务总览-跨项目时间轴-甘特图进度条组件 -->
  <div
    v-if="visible"
    class="box"
    v-for="(task, index) in tasks"
    :key="index"
    :style="{
      width: task.width - 6 + 'px',
      background: task.boxStyle.bgColor,
      color: task.boxStyle.textColor,
      left: task.leftOffset + 'px' // 左移距离
    }"
    @mouseenter="showTooltip(task, $event)"
    @mousemove="moveTooltip($event)"
    @mouseleave="hideTooltip"
  >
    <div v-if="task.risk === 1" class="box-warning">
      <img src="../assets/warning.svg" alt="">
    </div>
    <div class="box_title">{{ task.summary }}</div>
  </div>
  <div
    v-if="isTooltipVisible"
    class="box-tooltip"
    :style="{ top: tooltipY + 'px', left: tooltipX + 'px' }"
  >
    <div class="top-title">
      <p class="title">标题：{{ tooltipData.summary }}</p>
    </div>
  </div>
</template>
<script setup>
import { ref, watch } from 'vue'
import dayjs from 'dayjs'
import isBetween from 'dayjs/plugin/isBetween'
import { getBoxStyle } from '../utils/index.js'

// 扩展 dayjs 支持 isBetween 方法
dayjs.extend(isBetween)

const props = defineProps({
  time: String,
  row: Object,
  labelWidth: Number,
  minDate: String,
  maxDate: String
})

const visible = ref(false)

// Tooltip 控制
const isTooltipVisible = ref(false)
const tooltipX = ref(0)
const tooltipY = ref(0)

// 显示 tooltip
const tooltipData = ref({})
const showTooltip =async (text, event) => {
  if (text.hasOwnProperty('issuestatus')) {
    isTooltipVisible.value = true
    tooltipData.value = text
    moveTooltip(event)
  }
}

// 隐藏 tooltip
const hideTooltip = () => {
  isTooltipVisible.value = false
}

// 跟随鼠标移动
const moveTooltip = (event) => {
  tooltipX.value = event.clientX + 15
  tooltipY.value = event.clientY + 15
}

// 计算日期差
const calculateDateDifference = (startDateStr, endDateStr, minDateStr, maxDateStr) => {
  if (!startDateStr || !endDateStr) return 0

  const startDate = dayjs(startDateStr)
  const endDate = dayjs(endDateStr)
  const minDate = dayjs(minDateStr)
  const maxDate = dayjs(maxDateStr)

  /// 如果开始日期早于筛选的最小日期，则从最小日期开始
  const adjustedStartDate = startDate.isBefore(minDate) ? minDate : startDate

  // 如果结束日期晚于筛选的最大日期，则结束于最大日期
  const adjustedEndDate = endDate.isAfter(maxDate) ? maxDate : endDate

  // 计算天数差异
  // 初始化总宽度
  let totalWidth = 0

  // 按月分割任务时间段
  let currentMonthStart = adjustedStartDate.startOf('month')
  while (currentMonthStart.isBefore(adjustedEndDate)) {
    const currentMonthEnd = currentMonthStart.endOf('month')

    // 计算当前月份的实际起止时间
    const segmentStart = adjustedStartDate.isAfter(currentMonthStart)
        ? adjustedStartDate
        : currentMonthStart
    const segmentEnd = adjustedEndDate.isBefore(currentMonthEnd)
        ? adjustedEndDate
        : currentMonthEnd

    // 当前月份的天数
    const daysInMonth = currentMonthStart.daysInMonth()

    // 每天的宽度
    const dailyWidth = props.labelWidth / daysInMonth

    // 当前段的天数差异
    const timeDiff = segmentEnd.diff(segmentStart, 'day') + 1

    // 累加当前段的宽度
    totalWidth += timeDiff * dailyWidth

    // 移动到下一个月
    currentMonthStart = currentMonthStart.add(1, 'month').startOf('month')
  }

  return totalWidth
}

// 动态获取时间字段
const getTimeFields = (task) => {
  const startTime = dayjs(task.startTime)
  const endTime = dayjs(task.endTime)
  return { startTime, endTime }
}

const getMonthRange = (time, taskStartTime) => {
  // 动态获取任务开始时间的年份
  const taskYear = dayjs(taskStartTime).format('YYYY')

  // 构造当前时间范围的第一个月第一天
  const monthStart = dayjs(`${taskYear}-${time.replace('月', '')}-01`)

  // 构造当前时间范围的最后一天
  const monthEnd = monthStart.endOf('month')

  return { monthStart, monthEnd }
}

// 监听时间变化
const tasks = ref([])
watch(() => [props.time, props.row], ([time, row]) => {
  let visibleTasks = [];
  for (const taskKey in row) {
    const task = row[taskKey]
    const { startTime, endTime } = getTimeFields(task)
    const { monthStart, monthEnd } = getMonthRange(time.month, startTime) // 动态计算月份的起始和结束日期

    // 判断任务是否在当前月份范围内
    if (
      startTime.isBetween(monthStart, monthEnd, null, '[]') &&
      time.key === `${startTime.format('YYYY')}-${startTime.format('MM')}`
    ) {

      // 计算每日宽度
      const daysInMonth = monthStart.daysInMonth();
      const dailyWidth = props.labelWidth / daysInMonth;
      
      // 提取开始日期并计算左移距离
      const startDay = startTime.date();
      const leftOffset = startDay * dailyWidth;

      visibleTasks.push({
        width: calculateDateDifference(
          startTime,
          endTime,
          props.minDate,
          props.maxDate
        ),
        leftOffset, // 左移距离
        summary: task.taskFrameName || task.configName,
        ...task,
        boxStyle: getBoxStyle(task)
      })
    }
  }

  // 更新状态
  visible.value = visibleTasks.length > 0
  tasks.value = visibleTasks
}, { immediate: true })
</script>
<style lang="scss" scoped>
.box {
  position: absolute;
  display: flex;
  justify-content: center;
  align-items: center;
  height: auto;
  color: #FFFFFF;
  top: 0;
  left: 0;
  gap: 5px;
  margin-top: 8px;
  padding: 6px;
  border-radius: 2px;
  box-shadow: 0 0 6px 0 rgba(138, 147, 152, 0.25);
  box-sizing: border-box;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  z-index: 1;
  .box_title {
    width: 100%;
    font-size: 14px;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .box-warning {
    display: flex;
    align-items: center;
    justify-content: center;
  }
}

.box-tooltip {
  position: fixed;
  width: 310px;
  min-height: 296px;
  color: #ffffff;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  border-radius: 18px;
  background: #fff;
  z-index: 2;
  .top-title {
    height: 78px;
    border-radius: 18px 18px 0px 0px;
    background: #5F8FF9;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    padding-left: 26px;
    position: relative;
    .title {
      color: #FFF;
      font-family: "Alibaba PuHuiTi 3.0";
      font-size: 16px;
      font-style: normal;
      font-weight: 700;
      line-height: 21px;
      white-space: nowrap;
      overflow: hidden; 
      text-overflow: ellipsis; 
      width: 100%;
      text-align: left;
    }
  }
  .top-title:before{
    content: '';
    display: inline-block;
    position: absolute;
    width: 0;
    height: 0;
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
    border-top: 10px solid #5F8FF9;
    bottom: -10px;
    left: 35px;
  }
}
</style>